using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using System.Xml.Serialization;
using System.Collections;
using System.Reflection;
using TXLooker.Common;

namespace TXLooker.WorkItemExtention.Core
{
    /// <summary>
    /// Work Item Extention Application Settings
    /// </summary>
    [Serializable]
    public class WorkItemAppConfigs : ICloneable
    {
        #region Class Properties

        /// <summary>
        /// 
        /// </summary>
        public bool AutomaticUpdate
        {
            get { return this.m_bAtomaticUpdate; }
            set { this.m_bAtomaticUpdate = value; }
        }
        private bool m_bAtomaticUpdate = false;

        /// <summary>
        /// 
        /// </summary>
        public int AutomaticUpdatePeriod
        {
            get { return this.m_updatePeriod; }
            set
            {
                if (value < 0)
                    throw new ArgumentException();

                this.m_updatePeriod = value;
            }
        }
        private int m_updatePeriod = 30;

        #endregion Properties

        public IEnumerable<WIProjectSettings> GetProjectSettingsList(Uri serverUri)
        {
            try
            {
                List<WIProjectSettings> results = null;

                lock (this.m_projectSettingsMAP)
                {
                    Hashtable table = this.m_projectSettingsMAP[serverUri] as Hashtable;

                    if (table != null)
                    {
                        results = new List<WIProjectSettings>();

                        foreach (WIProjectSettings item in table.Values)
                            results.Add(item);
                    }
                }

                return results;
            }
            catch (Exception ex)
            {
                LogManager.WriteMessageToCustomLog("Error (GetProjectSettingsList) WorkItemAppSettings " + ex.Message);
                return null;
            }
        }
        public WIProjectSettings GetProjectSettings(Uri projectUri)
        {
            try
            {
                WIProjectSettings result = null;

                lock (this.m_projectSettingsMAP)
                {
                    foreach (Hashtable table in this.m_projectSettingsMAP.Values)
                    {
                        if (table.ContainsKey(projectUri))
                        {
                            result = new WIProjectSettings();
                            result.Init((WIProjectSettings)table[projectUri]);
                            break;
                        }
                    }
                }
                return result;
            }
            catch (Exception ex)
            {
                LogManager.WriteMessageToCustomLog("Error (GetProjectSettings) WorkItemAppSettings " + ex.Message);
                return null;
            }
        }
        public void SetProjectSettings(IEnumerable<WIProjectSettings> settings)
        {
            try
            {
                lock (this.m_projectSettingsMAP)
                {
                    foreach (WIProjectSettings item in settings)
                    {
                        Hashtable table = this.m_projectSettingsMAP[item.ServerUri] as Hashtable;
                        if (table == null)
                        {
                            table = new Hashtable();
                            this.m_projectSettingsMAP[item.ServerUri] = table;
                        }
                        table[item.ProjectUri] = item;
                    }
                }
            }
            catch (Exception ex)
            {
                LogManager.WriteMessageToCustomLog("Error (SetProjectSettings) WorkItemAppSettings " + ex.Message);
            }
        }
        public void RemoveProjectSettings(IEnumerable<WIProjectSettings> settings)
        {
            try
            {
                lock (this.m_projectSettingsMAP)
                {
                    foreach (WIProjectSettings item in settings)
                    {
                        if (this.m_projectSettingsMAP.ContainsKey(item.ServerUri))
                            (this.m_projectSettingsMAP[item.ServerUri] as Hashtable).Remove(item.ProjectUri);
                    }
                }
            }
            catch (Exception ex)
            {
                LogManager.WriteMessageToCustomLog("Error (RemoveProjectSettings) WorkItemAppSettings " + ex.Message);
            }
        }
        public void ClearProjectSettings()
        {
            try
            {
                lock (this.m_projectSettingsMAP)
                {
                    this.m_projectSettingsMAP.Clear();
                }
            }
            catch (Exception ex)
            {
                LogManager.WriteMessageToCustomLog("Error (ClearProjectSettings) WorkItemAppSettings " + ex.Message);
            }
        }

        //key - server Uri, value - hashtable(projectUri, ProjectSettings)
        public Hashtable ProjectSettingsMAP
        {
            get { return this.m_projectSettingsMAP; }
            set { this.m_projectSettingsMAP = value; }
        }
        public Hashtable m_projectSettingsMAP = new Hashtable();

        public WorkItemAppConfigs()
        { }

        #region ICloneable Members

        public object Clone()
        {
            WorkItemAppConfigs clone = new WorkItemAppConfigs();
            clone.SetDataFrom(this);
            return clone;
        }

        #endregion

        public void SetDataFrom(WorkItemAppConfigs configs)
        {
            this.AutomaticUpdate = configs.AutomaticUpdate;
            this.AutomaticUpdatePeriod = configs.AutomaticUpdatePeriod;
        }
        public void SetDataFrom(object configs)
        {
            try
            {
                //Type conversion error.. So  use reflection
                Type type = configs.GetType();

                this.AutomaticUpdate = (bool)type.InvokeMember("AutomaticUpdate", BindingFlags.GetProperty, null, configs, null);
                this.AutomaticUpdatePeriod = (int)type.InvokeMember("AutomaticUpdatePeriod", BindingFlags.GetProperty, null, configs, null);

                this.ProjectSettingsMAP = (Hashtable)type.InvokeMember("ProjectSettingsMAP", BindingFlags.GetProperty, null, configs, null);

                Hashtable tttt = new Hashtable();

                foreach (Uri serverUri in this.ProjectSettingsMAP.Keys)
                {
                    Hashtable ht = (Hashtable)this.ProjectSettingsMAP[serverUri];

                    Hashtable temp = new Hashtable();

                    foreach (Uri projectUri in ht.Keys)
                    {
                        WIProjectSettings s = new WIProjectSettings();
                        s.SetDataFrom(ht[projectUri]);

                        temp[projectUri] = s;
                    }

                    tttt[serverUri] = temp;
                }

                this.ProjectSettingsMAP = tttt;
            }
            catch (Exception ex)
            {
                LogManager.WriteMessageToCustomLog("Error (SetDataFrom) WorkItemAppSettings " + ex.Message);

            }
        }
    }
}
